package cn.skyclass.net
{
	import flash.utils.Dictionary;
	
	import mx.messaging.ChannelSet;
	import mx.messaging.channels.AMFChannel;
	import mx.rpc.remoting.RemoteObject;
	
	/**
	 * 用于 remote object 的管理
	 * 
	 * 使用前必需先行调用 initChannelSet(uri:String=null):void 来对信道进行初始化
	 */
	public class RoPool
	{
		public function RoPool(singletonEnforcer:SingletonEnforcer){}

		/**
		 * 存储多个实例的字典
		 */
		private static var instanceDic:Dictionary = new Dictionary();
				
		public static function getInstance(instanceName:String="default"):RoPool{
			// 根据实例名称从字典中查找实例，如果未找到，则新建一个实例并加入字典中并返回此实例
			var instance:RoPool = instanceDic[instanceName];
			if(instance == null){
				instance = new RoPool(new SingletonEnforcer());
				instance.instanceName = instanceName;
				instanceDic[instanceName] = instance;
			}
			return instance;			
		}		


		/**
		 * 当前实例的名称
		 */
		public var instanceName:String;
		
		/**
		 * 是否已完成初始化
		 */
		public var initialized:Boolean;
				
		private var roDic:Dictionary = new Dictionary();
		private var channelSet:ChannelSet;
		
		
		/**
		 * 初始化信道信息
		 * 
		 * @param uri used to create the whole endpoint URI for a channel
		 * 		eg: http://localhost:8080/java-web-tester/messagebroker/amf
		 * 		default: http://{server.name}:{server.port}/{context.root}/messagebroker/amf
		 */
		public function initChannelSet(uri:String=null):void{
			if(initialized){
				return;
			}
			
			if(!uri){
				uri = URLUtilEx.getSiteRootUrl() + "messagebroker/amf";
			}
			
			var channel:AMFChannel = new AMFChannel();
			channel.url = uri;
			
			channelSet = new ChannelSet();
			channelSet.addChannel(channel);
			
			initialized = true;
		}
		
		/**
		 * 获取 remote object 所使用的信道信息
		 */
		public function getChannelSet():ChannelSet{
			return channelSet;
		}
		
		/**
		 * 根据键值来获取指定的 remote object，
		 * 若不存在，则返回 null
		 */
		public function getRemoteObject(key:String):RemoteObject{
			return this.roDic[key];
		}
		
		/**
		 * 将一个 remote object 放入池中。
		 * 若此 remote object 已经存在，则替换之并返回旧的 remote object，
		 * 否则直接将此 remote object 加入池中，并返回 null
		 */
		public function putRemoteObject(key:String, ro:RemoteObject):RemoteObject{
			var old:RemoteObject = this.roDic[key];
			this.roDic[key] = ro;
			return old;
		}
		
	}
}


// just can access this class in this file
class SingletonEnforcer {}

